package hn.sigit.interop.gmlproducers;

import java.util.ArrayList;
import java.util.List;

import org.deegree.commons.tom.primitive.PrimitiveType;
import org.deegree.cs.CRS;
import org.deegree.feature.GenericFeature;
import org.deegree.feature.property.GenericProperty;
import org.deegree.feature.property.Property;
import org.deegree.feature.property.SimpleProperty;
import org.deegree.feature.types.GenericFeatureType;
import org.deegree.feature.types.property.ArrayPropertyType;
import org.deegree.feature.types.property.GeometryPropertyType;
import org.deegree.feature.types.property.PropertyType;
import org.deegree.feature.types.property.SimplePropertyType;
import org.deegree.feature.types.property.ValueRepresentation;
import org.deegree.feature.types.property.GeometryPropertyType.CoordinateDimension;
import org.deegree.feature.types.property.GeometryPropertyType.GeometryType;
import org.deegree.geometry.points.Points;
import org.deegree.geometry.primitive.LinearRing;
import org.deegree.geometry.primitive.Ring;
import org.deegree.geometry.standard.primitive.DefaultLinearRing;
import org.deegree.geometry.standard.primitive.DefaultPolygon;
import org.deegree.gml.GMLVersion;

import hn.sigit.model.commons.IParcel;

public class ParcelGMLProducer extends GMLProducer<IParcel> {
	private static final SimplePropertyType parcelIdType = new SimplePropertyType(newQName("id"), 1, 1, PrimitiveType.STRING, false, false, null);
	private static final SimplePropertyType parcelFieldTabType = new SimplePropertyType(newQName("fieldTab"), 1, 1, PrimitiveType.DECIMAL, false, false, null);
	private static final SimplePropertyType parcelMunicipalKeyType = new SimplePropertyType(newQName("municipalKey"), 1, 1, PrimitiveType.STRING, false, false, null);
	private static final SimplePropertyType parcelCadastralKeyType = new SimplePropertyType(newQName("cadastralKey"), 1, 1, PrimitiveType.STRING, false, false, null);
	private static final ArrayPropertyType parcelRRRPropertyType = new ArrayPropertyType(newQName("RRR"), 1, 1, false, false, null);
	private static final GeometryPropertyType parcelGeometryType = new GeometryPropertyType(newQName("geometry"), 1, 1, false, false, null, GeometryType.POLYGON, CoordinateDimension.DIM_2, ValueRepresentation.BOTH);
	
	private static GenericFeatureType parcelFeatureType;

	
	static {
		parcelFeatureType = buildFeatureType();
	}
	
	private static GenericFeatureType buildFeatureType() {
		List<PropertyType> propertyTypeList = new ArrayList<PropertyType>();
		propertyTypeList.add(parcelIdType);
		propertyTypeList.add(parcelFieldTabType);
		propertyTypeList.add(parcelMunicipalKeyType);
		propertyTypeList.add(parcelCadastralKeyType);
		propertyTypeList.add(parcelRRRPropertyType);
		propertyTypeList.add(parcelGeometryType);

		return new GenericFeatureType(newQName("Parcel"), propertyTypeList, false);
	}
	
	@Override
	public GenericFeature buildFeature() {
		return buildFeature(true);
	}
	public GenericFeature buildFeature(boolean includeRRR) {
		IParcel parcel = getObjectFeature();
		
		SimpleProperty parcelId = new SimpleProperty(parcelIdType, String.valueOf(parcel.getSuID()), PrimitiveType.STRING);
		SimpleProperty parcelFieldTab = new SimpleProperty(parcelFieldTabType, String.valueOf(parcel.getFieldTab()), PrimitiveType.DECIMAL);
		SimpleProperty parcelMunicipalKey = new SimpleProperty(parcelMunicipalKeyType, nvl(parcel.getMunicipalKey()), PrimitiveType.STRING);
		SimpleProperty parcelCadastralKey = new SimpleProperty(parcelCadastralKeyType, nvl(parcel.getCadastralKey()), PrimitiveType.STRING);
		GenericProperty parcelRRR = null; 
		
		if (includeRRR)
			parcelRRR = PropertyGMLProducer.buildRRRProperty(getJurisdictionCode(), parcel.getProperty(), parcelRRRPropertyType);

        com.vividsolutions.jts.geom.Polygon jtsPolygon = parcel.getShape();
        CRS crs = getWorkingCRS();
        
        Points exteriorPoints = getAsPoints( jtsPolygon.getExteriorRing().getCoordinateSequence(), crs );
        LinearRing exteriorRing = new DefaultLinearRing( null, crs, null, exteriorPoints );
        List<Ring> interiorRings = new ArrayList<Ring>( jtsPolygon.getNumInteriorRing() );
        for ( int i = 0; i < jtsPolygon.getNumInteriorRing(); i++ ) {
            Points interiorPoints = getAsPoints( jtsPolygon.getInteriorRingN( i ).getCoordinateSequence(), crs );
            interiorRings.add( new DefaultLinearRing( null, crs, null, interiorPoints ) );
        }
        DefaultPolygon dp = new DefaultPolygon( null, crs, null, exteriorRing, interiorRings );

		GenericProperty parcelGeometry = new GenericProperty(parcelGeometryType, dp);
		
		List<Property> propertyList = new ArrayList<Property>();
		propertyList.add(parcelId);
		propertyList.add(parcelFieldTab);
		propertyList.add(parcelMunicipalKey);
		propertyList.add(parcelCadastralKey);
		if (parcelRRR != null)
			propertyList.add(parcelRRR);
		propertyList.add(parcelGeometry);
		
		
		return new GenericFeature(parcelFeatureType, String.valueOf(parcel.getSuID()), propertyList, GMLVersion.GML_31);
	}

	
	public ParcelGMLProducer(String jurisdictionCode, IParcel parcel) {
		super(jurisdictionCode, parcel);
	}

	public IParcel getParcel() {
		return getObjectFeature();
	}
	
}
